import type { Options } from '@/try-on/config'
import type { OrthographicCamera } from 'three'
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'
import type { OrbitControls } from 'three/examples/jsm/Addons.js'
import type { Contrast } from './contrast'
import type { SceneManager } from '.'
export class Debug {
  #option: Options
  gui = new GUI()
  pdCallback?: (index: number, value: number) => void
  pdSlider
  scene
  sliderColorCallback?: (color: string) => void
  constructor(
    options: Options,
    container: Element,
    control: OrbitControls,
    camera: OrthographicCamera,
    contrast: Contrast,
    scene: SceneManager,
  ) {
    const callbaks = {
      resetCameraPosition: function () {
        camera.position.set(0, 0, 1)
        camera.zoom = 1
        camera.scale.set(1, 1, 1)
        camera.rotation.set(0, 0, 0)
        camera.updateProjectionMatrix()
      },
      contrast: function () {
        if (contrast.enable) {
          contrast.disableClip()
        } else {
          contrast.enableClip()
        }
      },
      enlarge: () => {
        const ZoomResult = this.scene.enlargeCamera()
        const enlargeButton = this.gui.controllers.find((item) => item._name == '相机放大')
        const shrinkButton = this.gui.controllers.find((item) => item._name == '相机缩小')
        if (ZoomResult.enlargeDisable) {
          enlargeButton?.disable()
        } else {
          enlargeButton?.enable()
        }
        if (ZoomResult.shrinkDisable) {
          shrinkButton?.disable()
        } else {
          shrinkButton?.enable()
        }
      },
      shrink: () => {
        const ZoomResult = this.scene.shrinkCamera()
        const enlargeButton = this.gui.controllers.find((item) => item._name == '相机放大')
        const shrinkButton = this.gui.controllers.find((item) => item._name == '相机缩小')
        if (ZoomResult.enlargeDisable) {
          enlargeButton?.disable()
        } else {
          enlargeButton?.enable()
        }
        if (ZoomResult.shrinkDisable) {
          shrinkButton?.disable()
        } else {
          shrinkButton?.enable()
        }
      },
    }
    this.#option = options
    this.scene = scene
    this.gui.title('Debug')
    this.gui
      .add(this.#option.three, 'control')
      .name('相机控制')
      .onChange((v) => {
        control.enableDamping = v
        control.enablePan = v
        control.enableRotate = v
        control.enableZoom = v
        control.enabled = v
      })
    this.gui.add(callbaks, 'resetCameraPosition').name('重置相机视角')
    this.gui.add(callbaks, 'contrast').name('切换对照')
    const numbers = this.#option.tryOn.pdScale.map((item) => Number(item.label))
    const max = Math.max(...numbers)
    const min = Math.min(...numbers)
    this.pdSlider = this.gui
      .add(this.#option.tryOn, 'defaultScale', min, max, 1)
      .name('瞳距')
      .onChange((v) => {
        const index = this.#option.tryOn.pdScale.findIndex((item) => item.label == v)
        const value = this.#option.tryOn.pdScale[index].value
        if (this.pdCallback) this.pdCallback(index, value)
      })
    this.gui.add(callbaks, 'enlarge').name('相机放大')

    this.gui.add(callbaks, 'shrink').name('相机缩小').disable()
    this.gui
      .addColor(this.#option.tryOn, 'sliderColor')
      .name('瞳距滑块颜色')
      .onChange((v) => {
        if (this.sliderColorCallback) {
          this.sliderColorCallback(v)
        }
      })
    container.appendChild(this.gui.domElement)
  }
  pdOnChange(callbak: (index: number, value: number) => void) {
    this.pdCallback = callbak
  }
  sliderColorChange(callbak: (color: string) => void) {
    this.sliderColorCallback = callbak
  }
}
